﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Data.Linq;
using System.Reflection;

namespace VIT.DataHelper.DataAccess
{
    public abstract class LinqHelper<TDatabase> where TDatabase : DataContext, new()
    {
        public static List<T> ReturnAllRows<T>() where T : class
        {
            return new TDatabase().GetTable<T>().ToList<T>();
        }

        public static bool EntityExists<T>(Expression<Func<T, bool>> predicate)
        where T : class
        {
            return new TDatabase().GetTable<T>().Where<T>(predicate).Count() > 0;
        }

        public static List<T> Filter<T>(Expression<Func<T, bool>> predicate)
        where T : class
        {
            return new TDatabase().GetTable<T>().Where(predicate).ToList<T>();
        }        

        public static void Insert<T>(T instance) where T : class
        {
            using (TDatabase database = new TDatabase())
            {
                database.GetTable<T>().InsertOnSubmit(instance);
                database.SubmitChanges();
            }
        }

        public static void Update<T>(Expression<Func<T, bool>> predicate, T entity) where T : class
        {
            if (!EntityExists<T>(predicate))
                using (TDatabase database = new TDatabase())
                {
                    T t = (T)database.GetTable<T>().Where<T>(predicate).Single();

                    foreach (PropertyInfo p in t.GetType().GetProperties())
                        p.SetValue(t, p.GetValue(entity, null), null);

                    database.SubmitChanges();
                }
        }  

        public static void Delete<T>(Expression<Func<T, bool>> predicate)
        where T : class
        {
            using (TDatabase database = new TDatabase())
            {
                T t = (T)database.GetTable<T>().Where<T>(predicate).Single();
                database.GetTable<T>().DeleteOnSubmit(t);
                database.SubmitChanges();
            }
        }









        ////How to Use

        ////get
        //var foo = DataAccess<FooDB>.GetRecord<Foo>(f => f.Name == "Stihl 066");

        //// insert
        //Employee will = new Employee
        //{
        //   Username = "will.asrari",
        //   EmailAddress = "me@willasrari.com",
        //   CanCode = true
        //};
        //LinqHelper.Insert<Employee>(will); 

        //// delete
        //LinqHelper.Delete(emp => emp.EmployeeId.Equals(3));
    }
}
